# coding=utf-8
import re, random
from flask import Flask, current_app, make_response, jsonify, request, session

from . import api
from aihome.utils.captcha.captcha import captcha
from aihome import redis_store
from aihome import constants, db
from aihome.utils.response_code import RET
from aihome.utils.sms import CCP
from aihome.models import User


@api.route('/imagecode/<image_code_id>', methods=['GET'])
def generate_image_code(image_code_id):
    """
    生成图片验证码
    1.调用captcha扩展包,生成图片验证码,name,text,image
    2.在redis中保存验证码内容
    3.返回图片本身，设置响应类型
    4.调用make_response
    :param image_code_id:
    :return:
    """
    # 生成图片验证码
    name, text, image = captcha.generate_captcha()
    # 存储图片验证码
    try:
        redis_store.setex('Imagecode' + image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)
    except Exception as e:
        # 调用上下文，记录项目错误日志信息
        current_app.logger.error(e)
        # 返回错误给前端
        return jsonify(error=RET.DBERR, errmsg='保存图片验证码失败')
    # 如果未发生异常返回图片本身
    else:
        # 使用响应对象,用来返回图片
        response = make_response(image)
        # # 设置响应报文的Content-Type = 'image/jpg'
        response.headers['Content-Type'] = 'image/jpg'
        # 返回响应对象
        return response


@api.route('/smscode/<mobile>', methods=['GET'])
def send_sms_code(mobile):
    """
    1.获取图片验证码
    2.获取图片uuid
    3.校验参数是否完整
    4.判断手机号格式
    5.从redis中查询验证码,判断是否过期
    6.删除验证码
    7.判断验证码是否正确
    8.查询用户是否已经注册
    9.调用云通讯发送短信验证码
    10.判断是否发送成功
    11.保存验证码
    12.返回结果

    :param mobile:
    :return:
    """

    imager_text = request.args.get('text')
    imager_imagecode = request.args.get('id')
    # 校验参数
    if not all([mobile, imager_text, imager_imagecode]):
        return jsonify(error=RET.PARAMERR, errmsg='参数缺失')
    # 判断手机号码
    if not re.match(r'^1[3-9]\d{9}$', mobile):
        return jsonify(error=RET.PARAMERR, errmsg='手机号码格式不对')
    # 从redis中获取图片验证码内容
    try:
        text = redis_store.get('Imagecode' + imager_imagecode)
    except Exception as e:
        # 调用上下文记录日志错误信息
        current_app.logger.error(e)
        return jsonify(error=RET.DBERR, errmsg='redis异常')
    # 如果redis中验证码不存在
    if not text:
        return jsonify(error=RET.NODATA, errmsg='图片已过期')
    # 删除验证码
    try:
        redis_store.delete('Imagecode' + imager_imagecode)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(error=RET.DBERR, errmsg='redis删除图片验证码异常')

    # 判断验证码是否一致，忽略大小写
    if text.lower() != imager_text.lower():
        return jsonify(error=RET.DATAERR, errmsg='图片验证码错误')
    # 判断用户是否已经注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(error=RET.DBERR, errmsg='查询User异常')
    if user is not None:
        return jsonify(error=RET.DBERR, errmsg='手机号已注册')
    # 生成短信验证码
    sms_code = '%06d' % random.randint(0, 999999)
    # 保存验证码到redis
    try:
        redis_store.setex('SMScode' + mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)
    except Exception as e:
        return jsonify(error=RET.DBERR, errmsg='redis数据库异常')
    # 实例云通讯
    ccp = CCP()
    # 发送验证码
    try:
        result = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_REDIS_EXPIRES/60], 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(error=RET.THIRDERR, errmsg='发送短信异常')
    # 判断是否发送成功
    if 0 == result:
        return jsonify(errno=RET.OK,errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR,errmsg='发送失败')


@api.route('/users', methods=['POST'])
def register():
    """
    1.获取json数据：request.get_json()
    2.获取参数：手机号，手机验证码， 密码，校验参数是否完整
    3.判断手机格式,判断用户是否注册
    4.判断短信验证码是否正确，
    5.如果正确删除redis存储，
    6.给密码进行加密
    7.存储用户信息
    8.写入session
    9.返回结果
    :return:
    """
    # 获取json数据
    user_data = request.get_json()
    if not user_data:
        return jsonify(errno=RET.DBERR, errmsg='获取json数据失败')
    mobile = user_data.get('mobile')
    password = user_data.get('password')
    sms_code = user_data.get('sms_code')
    # 校验参数
    if not all([mobile, password, sms_code]):
        return jsonify(errno=RET.DBERR, errmsg='参数缺失')
    # 判断手机格式
    if not re.match(r'^1[3-9]\d{9}', mobile):
        return jsonify(errno=RET.DBERR, errmsg='手机号格式错误')
    # 查询手机号是否已经注册
    try:
        user = User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='从数据库查询手机号异常')
    if user is not None:
        return jsonify(errno=RET.DBERR, errmsg='手机号码已注册')
    # 查询手机验证码
    try:
        ret = redis_store.get('SMScode' + mobile)
        print ret
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='数据库查询手机验证码异常')
    # 判断验证码是否过期
    if not ret:
        return jsonify(errno=RET.DBERR, errmsg='手机验证码已过期')
    # 判断验证码是否一致
    if ret != str(sms_code):
        return jsonify(errno=RET.DBERR, errmsg='手机号验证码错误')
    # 删除验证码
    try:
        redis_store.delete('SMScode' + mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='删除手机验证码数据库异常')
    # 保存用户信息
    # 实例user对象
    user = User(mobile=mobile, name=mobile)
    # 调用模型类中的方法generate_password_hash,对密码进行加密sha256处理
    user.password = password
    try:
        # 将user添加到数据库
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        # 记录错误日志信息
        current_app.logger.error(e)
        # 如果发生异常就回滚
        db.session.rollback()
    # 写入session
    session['user_id'] = user.id
    session['mobile'] = mobile
    session['name'] = mobile
    return jsonify(errno=RET.OK, errmsg='OK', data=user.to_dict())

